package com.lmaos.basetools.control;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import com.lmaos.allcontrol.beancontrol.class_.ClassUtils;
import com.lmaos.allcontrol.beancontrol.field_.FieldUtils;
import com.lmaos.allcontrol.beancontrol.method_.MethodUtils;
import com.lmaos.basetools.base.SArrayUtils;
import com.lmaos.basetools.base.SParamMap;
import com.lmaos.basetools.sText.TextUtils;
import com.lmaos.basetools.sText.XmlUtils;

public class SControlUtils {
	public static class DefaultConf{
		public String default_encode;
		public String default_contentType;
	}
	public static DefaultConf getDefaultConf(String xml){
		DefaultConf defaultConf = new DefaultConf();
		Document root_doc = XmlUtils.getDoucmentByClassPath(xml);
		defaultConf.default_encode = TextUtils.ifIsBlankSetValue(root_doc.getDocumentElement().getAttribute("encode"), "UTF-8"); // 设置绝对全局默认编码
		defaultConf.default_contentType = TextUtils.ifIsBlankSetValue(root_doc.getDocumentElement().getAttribute("contentType"), ""); // 设置绝对全局默认编码
		return defaultConf;
	}
	
	public static List<Object> getSControlObjs(String xml){
				List<Object> objs = new ArrayList<Object>();
		List<Document> docs = XmlUtils.getIncludeDocumentByClassPath(xml, SControl.class.getClassLoader(), "include", "file");
		for (Document doc : docs) {
			NodeList controlNodes = doc.getElementsByTagName("control");
			for (int i = 0; i < controlNodes.getLength(); i++) {
				Element controlNode = XmlUtils.getElement(controlNodes, i);
				String classname = controlNode.getAttribute("class");
				Object controlObj = ClassUtils.getObject(classname);
				if(controlObj!=null){
					objs.add(controlObj);
				}
			}
		}
		return objs;
	}
	public static void loadSControl(Object controlObj,Map<String, SControlBean> controlBeans,Map<String, SControlInterceptBean> controlInterceptBeans,Map<String, SControlResultBean> controlResultBeans,String default_encode,String default_contentType){
//		loadSControlInterceptBeans(controlObj, controlInterceptBeans);
//		loadSControlBeans(controlObj, controlBeans,"",default_encode,defaule_contentType);
		loadSControlChilds(controlObj, controlBeans,controlInterceptBeans,controlResultBeans , default_encode, default_contentType);
//		loadSControlResultBeans(controlObj, controlResultBeans);
	}
	public static void loadSControlChilds(Object controlObj,Map<String, SControlBean> controlBeans,Map<String, SControlInterceptBean> controlInterceptBeans,Map<String, SControlResultBean> controlResultBeans,String default_encode,String default_contentType){
		List<SControlChild> controlChilds = getSControlChilds(controlObj, default_encode, default_contentType);
		for (SControlChild controlChild : controlChilds) {
			loadSControlInterceptBeans(controlChild, controlInterceptBeans);
			loadSControlBeans(controlChild, controlBeans);
			loadSControlResultBeans(controlChild, controlResultBeans);
		}
	}
	
	/**
	 * 说明：获取所有自控制对象		<br>
	 * 时间：2017年6月29日 下午2:40:47
	 *
	 * @param controlObj
	 * @param default_encode
	 * @param default_contentType
	 * @return
	 */
	public static List<SControlChild> getSControlChilds(Object controlObj, String default_encode, String default_contentType){
		List<SControlChild> controlChilds = new ArrayList<SControlChild>();
		SURLControl surlControl_root = controlObj.getClass().getAnnotation(SURLControl.class);
		String url_root = "";
		String[] interceptNames_root = {};
		String resultNames_root = "";
		String encode_root = default_encode;
		String contentType_root = default_contentType;
		if(surlControl_root!=null){
			url_root = surlControl_root.url();
			interceptNames_root = surlControl_root.interceptNames();
			resultNames_root = surlControl_root.resultName();
			encode_root = TextUtils.ifIsBlankSetValue(surlControl_root.encode(), default_encode);
			contentType_root = TextUtils.ifIsBlankSetValue(surlControl_root.contentType(), default_contentType);
		}
		
		controlChilds.add(new SControlChild
				(url_root, controlObj, null, interceptNames_root, resultNames_root, encode_root, contentType_root, "", "", ""));
		
		
		for (int i = 0; i < controlChilds.size(); i++) {
			SControlChild controlChild = controlChilds.get(i);
//			url_root = controlChild.getControlUrl();
			interceptNames_root = controlChild.getInterceptNames();
			resultNames_root = controlChild.getResultName();
			encode_root = controlChild.getEncode();
			contentType_root = controlChild.getContentType();
			
			
			Object controlObjSuper = controlChild.getControlObj();
			List<Field> childfields = FieldUtils.indexFieldByAnnotation(controlObjSuper.getClass(), SURLControl.class);
			for (Field childfield : childfields) {
				SURLControl control_annf = childfield.getAnnotation(SURLControl.class);
				Object controlObjChild = FieldUtils.getFieldValue(controlObjSuper, childfield.getName());
				if(controlObjChild == null){
					controlObjChild = ClassUtils.getObject(childfield.getType());
					FieldUtils.setFieldValue(controlObjSuper, childfield, controlObjChild);
				}
				String controlUrl = getUrl(url_root,control_annf.url());
				String[] interceptNames = control_annf.interceptNames();
				if(childfield.isAnnotationPresent(SURLControlNotVerify.class)){
					interceptNames = new String[]{};
				}else if(interceptNames.length == 0){
					interceptNames = interceptNames_root;
				}else if(control_annf.interceptExtend()){
					interceptNames = (String[]) SArrayUtils.merge(interceptNames_root,interceptNames);
				}
				String resultName = TextUtils.ifIsBlankSetValue(control_annf.resultName(),resultNames_root);		// 结果执行器
				String encode = TextUtils.ifIsBlankSetValue(control_annf.encode(), encode_root);					// 编码
				String contentType = TextUtils.ifIsBlankSetValue(control_annf.contentType(), contentType_root); // 文档类型
				String des = control_annf.des(); // 描述
				String asname = control_annf.asname();
				
				controlChilds.add(new SControlChild(controlUrl, controlObjChild, null, interceptNames, resultName, encode, contentType, des, asname,  controlUrl));
			}
			
		}
		return controlChilds;
	}
	
	/**
	 * 说明：加载控制器bean		<br>
	 * 时间：2017年6月21日 下午4:18:46
	 *
	 * @param controlObj
	 * @param controlBeans
	 */
	public static void loadSControlBeans(SControlChild controlChild,Map<String, SControlBean> controlBeans){
		Object controlObj = controlChild.getControlObj();
		SURLControl surlControl_root = controlObj.getClass().getAnnotation(SURLControl.class);
		String url_root = controlChild.getSuperUrl();
		String[] interceptNames_root = controlChild.getInterceptNames();
		String resultNames_root = controlChild.getResultName();
		String encode_root = controlChild.getEncode();
		String contentType_root = controlChild.getContentType();
		if(surlControl_root!=null){
			url_root = getUrl(url_root,surlControl_root.url());
			interceptNames_root = TextUtils.ifIsEmptySetValues(surlControl_root.interceptNames(), interceptNames_root);
			resultNames_root = TextUtils.ifIsBlankSetValue(surlControl_root.resultName(),resultNames_root);
			encode_root = TextUtils.ifIsBlankSetValue(surlControl_root.encode(), encode_root);
			contentType_root = TextUtils.ifIsBlankSetValue(surlControl_root.contentType(), contentType_root);
		}
		List<Method> methods = MethodUtils.indexMethodByAnnotation(controlObj.getClass(), SURLControl.class);
		for (Method controlMethod : methods) {
			SURLControl surlControl = controlMethod.getAnnotation(SURLControl.class);
			SURL surls = controlMethod.getAnnotation(SURL.class);
			List<String> urls = new ArrayList<String>();
			urls.add(surlControl.url());
			urls.addAll(Arrays.asList(surlControl.urls()));
			if(surls!=null){
				urls.addAll(Arrays.asList(surls.urls()));
			}
			String[] interceptNames = surlControl.interceptNames();;
			if(controlMethod.isAnnotationPresent(SURLControlNotVerify.class)){
				interceptNames = new String[]{};
			}else if(interceptNames.length == 0){
				interceptNames = interceptNames_root;
			}else if(surlControl.interceptExtend()){ // 继承父拦截效果,在执行子拦截效果
				interceptNames = (String[]) SArrayUtils.merge(interceptNames_root,interceptNames);
			}
			String resultName = TextUtils.ifIsBlankSetValue(surlControl.resultName(),resultNames_root);		// 结果执行器
			String encode = TextUtils.ifIsBlankSetValue(surlControl.encode(), encode_root);					// 编码
			String contentType = TextUtils.ifIsBlankSetValue(surlControl.contentType(), contentType_root); // 文档类型
			String des = surlControl.des(); // 描述
			String asname = surlControl.asname();
			String format = surlControl.format();
			for (String url : urls) {
				if(TextUtils.isBlank(url)){
					continue;
				}
				String controlUrl = getUrl(url_root,url);
				if(controlBeans.containsKey(controlUrl)){
					throw new SURLControlException(controlUrl+" 加载错误,已经存在当前url,class="+controlObj.getClass());
				}
				
				SControlBean controlBean = new SControlBean(controlUrl, controlObj, controlMethod, interceptNames, resultName, encode, contentType, des, asname, url_root,format,url);
				controlBeans.put(controlUrl, controlBean);
			}
		}
	}
	
	
	/**
	 * 说明：加载拦截器bean		<br>
	 * 时间：2017年6月21日 下午4:18:59
	 *
	 * @param controlObj
	 * @param controlInterceptBeans
	 */
	public static void loadSControlInterceptBeans(SControlChild controlChild,Map<String, SControlInterceptBean> controlInterceptBeans){
		Object controlObj = controlChild.getControlObj();
		SURLControl surlControl_root = controlObj.getClass().getAnnotation(SURLControl.class);
		String url_root = controlChild.getSuperUrl();
		String resultName_root = controlChild.getResultName();
		if(surlControl_root!=null){
			url_root = getUrl(url_root,surlControl_root.url());
			resultName_root = TextUtils.ifIsBlankSetValue(surlControl_root.resultName(),resultName_root);
		}
		List<Method> methods = MethodUtils.indexMethodByAnnotation(controlObj.getClass(), SURLControlIntercept.class);
		for (Method controlInterceptMethod : methods) {
			SURLControlIntercept controlIntercept = controlInterceptMethod.getAnnotation(SURLControlIntercept.class);
			String name = controlIntercept.name();
			if(!TextUtils.isBlank(url_root)){
				name = getUrl(url_root,name);
			}
			if(controlInterceptBeans.containsKey(name)){
				throw new SURLControlException(name+" 加载错误,已经存在当前拦截器,class="+controlObj.getClass());
			}
			String asname = controlIntercept.asname();
			String des = controlIntercept.des();
			String resultName = TextUtils.ifIsBlankSetValue(controlIntercept.resultName(),resultName_root);
			SControlInterceptBean interceptBean = new SControlInterceptBean(name, controlObj, controlInterceptMethod,asname,des,resultName);
			controlInterceptBeans.put(name, interceptBean);
		}
	}
	/**
	 * 说明：加载结果执行bean		<br>
	 * 时间：2017年6月21日 下午4:19:11
	 *
	 * @param controlObj
	 * @param controlResultBeans
	 */
	public static void loadSControlResultBeans(SControlChild controlChild,Map<String, SControlResultBean> controlResultBeans){
		Object controlObj = controlChild.getControlObj();
		SURLControl surlControl_root = controlObj.getClass().getAnnotation(SURLControl.class);
		String url_root = controlChild.getSuperUrl();
		String resultName_root = controlChild.getResultName();
		if(surlControl_root!=null){
			url_root = getUrl(url_root,surlControl_root.url());
			resultName_root = TextUtils.ifIsBlankSetValue(surlControl_root.resultName(),resultName_root);
		}
		List<Method> methods = MethodUtils.indexMethodByAnnotation(controlObj.getClass(), SURLControlResult.class);
		for (Method controlResultMethod : methods) {
			SURLControlResult controlResult = controlResultMethod.getAnnotation(SURLControlResult.class);
			String name = controlResult.name();
			if(!TextUtils.isBlank(url_root)){
				name = getUrl(url_root,name);
			}
			if(controlResultBeans.containsKey(name)){
				throw new SURLControlException(name+" 加载错误,已经存在当前结果执行器,class="+controlObj.getClass());
			}
			String asname = controlResult.asname();
			String des = controlResult.des();
			SControlResultBean interceptBean = new SControlResultBean(name, controlObj, controlResultMethod,asname,des);
			controlResultBeans.put(name, interceptBean);
		}
	}
	
	public static String getUrl(String...nodes){
		StringBuilder url = new StringBuilder(100);
		for (String node : nodes) {
			if(!TextUtils.isBlank(node)){
				int urllength = url.length();
				if(!node.startsWith("/")){
					if(urllength==0||url.charAt(urllength-1)!='/'){
						url.append("/");
					}
					url.append(node);
				}else{
					if(urllength==0){
						url.append(node);
					}else if(url.charAt(urllength-1)=='/'){
						url.replace(urllength-1, urllength, node);
					}else{
						url.append(node);
					}
				}
				
				
				
			}
		}
		return url.toString();
	}
	public static String vUrl(String url){
		if(url.startsWith("/")){
			return url;
		}
		return "/"+url;
	}
	public static String subUrl(String start,String url){
		if(TextUtils.isBlank(start)||start.equals("/")){
			return url;
		}
		if(!url.startsWith(start)){
			return url;
		}
		url = url.substring(start.length());
		if(!url.startsWith("/")){
			url = "/"+url;
		}
		return url;
	}
	public static List<SParamMap> getSControlAll(SControl control,String... showFields){
		List<SParamMap> result = new ArrayList<SParamMap>();
		List<SControlBean> controlBeans = control.getScontrolBeans();
		for (SControlBean controlBean : controlBeans) {
			SParamMap bean = new SParamMap();
			
			for (String showField : showFields) {
				Object value = FieldUtils.getFieldValue(controlBean, showField);
				if(value!=null){
					bean.put(showField, value);
				}
			}
			if(bean.size()>0){
				result.add(bean);
			}
		}
		return result;
	}
	
	public static class SURLControlException extends RuntimeException{
		
		private static final long serialVersionUID = 1L;

		public SURLControlException(String msg) {
			super(msg);
		}
	}
	
}
